package ks.client.controllers;

import ks.client.interfaces.ILobby;
import ks.client.interfaces.IProcessClientMessage;
import ks.framework.common.Message;

/**
 * Generic ControllerChain registered with client-side processor.
 * 
 * This class enables us to design a "Chain of Responsibilities" where 
 * extensibility is gained by appending additional agents to a list.
 * The processor locates the first controller in the chain that handles
 * the given message.
 * 
 * @author George Heineman
 */
public class ClientControllerChain implements IProcessClientMessage {


	/** The next ClientControllerChain in the chain. */
	protected ClientControllerChain next;
	
	/** 
	 * The terminal agent in the chain 
	 */
	public ClientControllerChain () {
		
	}

	/** 
	 * Helper function for constructing chain with the given agent as the next
	 * one to execute.
	 * 
	 * @param next   Next agent to manage controllers.
	 */
	public ClientControllerChain (ClientControllerChain next) {
		this();
		append(next);
	}

	/**
	 * Add agent to be the last one in the controller chain.
	 * 
	 * @param agent
	 */
	public void append (ClientControllerChain agent) {
		if (next == null) {
			next = agent;
			return;
		} 
		
		// append to next.
		next.append(agent);
	}
	
	/**
	 * Appeal to the next agent in the chain to process given message.
	 * 
	 * If there is no such agent then false is returned, otherwise that 
	 * agent is directed to process the message
	 * 
	 * @param lobby  {@link ILobby} for the client responding.
	 * @param m    {@link Message} object to be processed.
	 * @return <code>true</code> if someone took ownership of the message otherwise <code>false</code>
	 * 
	 */
	protected boolean next(ILobby lobby, Message m) {
		if (next == null) {
			return false;
		}
		
		return next.process(lobby, m);
	} 
	
	/**
	 * An agent in the chain processes the message if it can, but if not
	 * then the next agent in the chain has its turn.
	 * 
	 * Entities that extend this class should override this method appropriately.
	 */
	@Override
	public boolean process(ILobby lobby, Message m) {
		return false;
	} 
	
}
